package usi.ch.onto.yago;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import edu.smu.tspell.wordnet.Synset;
import edu.smu.tspell.wordnet.SynsetType;
import edu.smu.tspell.wordnet.WordNetDatabase;

public class SynonymLookup {

	public static final String NOMATCH_LIST = "resources/nomatch_db.txt";//
	public static final String INDEX = "resources/bigindex";
	public static Connection conn;
	public static PreparedStatement prep;
	public static String sqlinsert = "insert into meanstest(identifier,arg1,arg2,confidence,factname,filetype) VALUES(?,?,?,?,?,?);";
	public static Integer identifier = 271604235;

	public static void main(String[] args) throws SQLException,
			ClassNotFoundException, IOException {

		/**
		 * Read the file nomatchlist.txt
		 */
		ArrayList<String> termlist = new ArrayList<String>();

		try {
			// Open the file that is the first
			// command line parameter
			FileInputStream fstream = new FileInputStream(NOMATCH_LIST);
			// Get the object of DataInputStream
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;
			// Read File Line By Line
			while ((strLine = br.readLine()) != null) {
				// Print the content on the console
				termlist.add(strLine);
			}
			// Close the input stream
			in.close();
		} catch (Exception e) {// Catch exception if any
			System.err.println("Error: " + e.getMessage());
		}

		/**
		 * Connect to database, connection is persistant for all 4 different
		 * matching functions
		 */
		Class.forName("org.sqlite.JDBC");
		conn = DriverManager.getConnection("jdbc:mysql://localhost/yago",
				"root", "admin");
		if (!conn.isClosed())
			System.out.println("Successfully connected to "
					+ "MySQL server using TCP/IP...");

		/**
		 * Loop through list with terms and get the most probable synonym
		 */
		for (int i = 0; i < termlist.size(); i++) {
			ArrayList<String> synwordforms = null;
			try {
				synwordforms = getTopSynonym(termlist.get(i)); // SYNSET WITH
																// HIGHEST
																// PROBABILITY
																// HAS MORE THAN
																// ONE WORD, SO
																// THEY ALL GO
																// TO ARRAY

			} catch (Exception e) {
				System.out.println("No synonym for:  " + termlist.get(i));
				System.out.println("");
			}

			if (synwordforms != null) {
				for (int j = 0; j < synwordforms.size(); j++) {
					identifier++;
					System.out.println("Word: \"" + termlist.get(i) + "\""
							+ " = " + synwordforms.get(j));
					prep = conn.prepareStatement(sqlinsert);
					prep.setString(1, identifier.toString());
					prep.setString(2, termlist.get(i));
					prep.setString(3, synwordforms.get(j));
					prep.setString(4, "1.0");
					prep.setString(5, "means");
					prep.setString(6, "ArticleExtractor.txt");
					prep.execute();
				}
				System.out.println("");
			}

		}

	}

	public static List<String> getSynonymsFromList(List<String> listTerms) {
		List<String> listSynonyms = new ArrayList<String>();
		String synonym;
		for (String term : listTerms) {
			try {
				synonym = getOneSynonym(term);
				if (synonym.isEmpty() )
					listSynonyms.add(term);
				else
					listSynonyms.add(synonym);
			} catch (Exception ex) {
				// no synonym so adds the same to be output later
				listSynonyms.add(term);
			}
		}
		return listSynonyms;
	}

	public static String getOneSynonym(String searchstring)
			throws NullPointerException {

		String synonym = "";
		System.setProperty("wordnet.database.dir",
				"C:\\Program Files\\WordNet\\2.1\\dict");
		WordNetDatabase database = WordNetDatabase.getFileInstance();
		Synset[] synsets = database.getSynsets(searchstring); // 4, 5 synsets,
																// FIRST ARRAY

		String[] finalarray = null;

		if (synsets.length > 0) // If synsets are found
		{
			if (synsets.length > 1) // If there is more than one, max has to be
									// calculated
			{
				int probability = 0; // Initial probability set to 0
				String[] maxset = null; // Array to hold the synset with maximum
										// tagcount as we loop through all
										// synsets

				for (int i = 0; i < synsets.length; i++) // Loop through synsets
															// and get highest
															// tag count
				{
					int tagcountpersynset = synsets[i]
							.getTagCount(searchstring);

					if (tagcountpersynset > probability) {
						probability = tagcountpersynset;
						maxset = synsets[i].getWordForms();
					} // If this synset has maximum tagcount, set our flag

				}
				finalarray = maxset;

			} else { // There was just one synset
				finalarray = synsets[0].getWordForms();// Ako je bio samo joedan
														// synset, assign it to
														// the array

			}

		}

		if (finalarray != null && finalarray.length > 0)
			synonym = finalarray[0];

		return synonym;
	}

	/**
	 * Returns the array of the words which belong to the synset that had
	 * biggest Tag Count
	 * 
	 * @param wordForm
	 *            - word that we are looking the synonim for
	 * @return returnlist - list with synonims with high, equal probability,
	 *         belonging to one synset
	 */

	public static ArrayList<String> getTopSynonym(String searchstring)
			throws NullPointerException {

		// Get the synsets
		System.setProperty("wordnet.database.dir",
				"C:\\Program Files\\WordNet\\2.1\\dict");
		WordNetDatabase database = WordNetDatabase.getFileInstance();
		Synset[] synsets = database.getSynsets(searchstring); // 4, 5 synsets,
																// FIRST ARRAY

		String[] finalarray = null;

		if (synsets.length > 0) // If synsets are found
		{
			if (synsets.length > 1) // If there is more than one, max has to be
									// calculated
			{
				int probability = 0; // Initial probability set to 0
				String[] maxset = null; // Array to hold the synset with maximum
										// tagcount as we loop through all
										// synsets

				for (int i = 0; i < synsets.length; i++) // Loop through synsets
															// and get highest
															// tag count
				{
					String[] wordForms = synsets[i].getWordForms(); // Contents
																	// of one
																	// synset
					int tagcountpersynset = synsets[i]
							.getTagCount(searchstring);

					if (tagcountpersynset > probability) {
						probability = tagcountpersynset;
						maxset = wordForms;
					} // If this synset has maximum tagcount, set our flag

				}
				finalarray = maxset;

			} else { // There was just one synset
				finalarray = synsets[0].getWordForms();// Ako je bio samo joedan
														// synset, assign it to
														// the array

			}

		} else // There are no synsets found
		{

			finalarray = null;
		}

		/**
		 * Remove the equal element from the returning list
		 * 
		 * for (int i = 0; i < maxset.length; i++) {
		 * if(!maxset[i].equals(wordForm)){ returnlist.add(maxset[i]); } }
		 */

		ArrayList<String> returnlist = new ArrayList<String>(); // WordForm list
																// from highest
																// tagcount
																// synset(in the
																// end the exact
																// match is
																// removed eg:
																// maxsynset(boy)
																// = boy, young
																// male - so,
																// "boy is removed from this")
		for (int i = 0; i < finalarray.length; i++) {
			if (!finalarray[i].equals(searchstring)) {
				returnlist.add(finalarray[i]);

			}
		}

		return returnlist;
	}
}
